/**
 * Basic JTAG driver header file
 *
 * (c) 01/2005 Martin Strubel <hackfin@section5.ch>
 *
 * UNSTABLE! (API may change)
 *
 * $Id: jtag.h 75 2005-11-11 09:12:34Z jiez $
 *
 */

#define REGISTER unsigned long

#ifdef USE_FTDI
	struct Controller;
#	define CONTROLLER struct Controller *
#else
	struct chain_t;
#	define CONTROLLER struct chain_t *
#endif

// Debugging
#define HANDLE_ERROR(x) handleError(__FILE__, __LINE__, x)
////////////////////////////////////////////////////////////////////////////
// PROTOS

int      handleError(char *prefix, int line,  int error);

int      jtag_reset(CONTROLLER c, int cycles);
int      jtag_send(CONTROLLER c, const unsigned char *seq, unsigned long len);
int      jtag_receive(CONTROLLER c, unsigned char *seq, unsigned long len);
int      jtag_queue(CONTROLLER c, int queue);
int      jtag_flush(CONTROLLER c);
int      jtag_goto_state(CONTROLLER c, const char *state);

void     jtag_debug(CONTROLLER c);

// Basic functions: Might change.
int      shift_ir(CONTROLLER c, unsigned short cmd);
int      shift_dr_in_out(CONTROLLER c, REGISTER in, REGISTER *out, int exec);
int      shift_dr_out(CONTROLLER c, REGISTER *out);
int      shift_dr_out_msb(CONTROLLER c, REGISTER *out, int exec);
int      shift_dr_in_msb(CONTROLLER c, REGISTER in, int exec);
int      shift_dr16_out_msb(CONTROLLER c, REGISTER *out, int exec);
int      shift_dr16_in_msb(CONTROLLER c, REGISTER in, int exec);

/** Select Scan chain - send instruction
 * This function shifts in the argument into the JTAG instruction register.
 *
 * \param jtag_insn  the instruction value
 */

int      scanchain_select(int jtag_insn);

int      scanchain_rti(void);

int      scanchain_shiftout(REGISTER *out, int exec);

int      scanchain_shiftin(REGISTER in, int exec);

/** Load two instructions into the instruction loop
 *
 * Note that the EMUIR instruction loop must be configured to size 2
 * before using this function. This instruction requires that the
 * EMUIR scanchain was selected.
 *
 * \param ins0       First instruction to execute
 * \param ins1       Second instruction to execute
 * \param exec       EXEC: execute (Run-Test/Idle), UPDATE: only update
 *
 */

void     scanchain_shift_twoins(REGISTER ins0,
                                REGISTER ins1, int exec);

// values for exec:
#define UPDATE 1
#define EXEC   2

// FIXME: Remove these, once debugging is done.

// in state RUN_TEST_IDLE, UPDATE_DR, UPDATE_IR

extern const char s_jtag_shift_ir[];
extern const char s_jtag_shift_dr[];

// in state UPDATE_DR, UPDATE_IR, TEST_LOGIC_RESET

extern const char s_jtag_run_test_idle[];

// Any state:

extern const char s_jtag_test_logic_reset[];


